﻿using System;
using System.Collections.Generic;
using System.Text;
using CamPlug.Api;
using System.Drawing;
using AForge.Video.DirectShow;
using AForge.Video;

namespace CamPlug.WebCam.Plugin
{
	public class WebCamPlugin : IPlugin
	{
		public const string Name = "Webcam source";
		object SyncRoot = new object();
		PropertiesForm PropertiesForm;
		internal FilterInfoCollection VideoDevices;
		Bitmap CurrentFrame;

		public WebCamPlugin()
		{
			this.VideoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
		}

		string IPlugin.Name { get { return Name; } }

		public byte[] SaveSettings()
		{
			return new byte[0];
		}

		public void LoadSettings(byte[] settings)
		{
		}

		public void UpdateBitmap(Bitmap bitmap)
		{
			lock (SyncRoot)
			{
				if (CurrentFrame == null)
					return;

				using (var canvas = Graphics.FromImage(bitmap))
					canvas.DrawImage(CurrentFrame, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
			}
		}

		public void ShowPropertiesForm()
		{
			if (PropertiesForm == null)
				PropertiesForm = new PropertiesForm(this);
			if (!PropertiesForm.Visible)
				PropertiesForm.Show();
			PropertiesForm.BringToFront();
		}


		VideoCaptureDevice videoSource;
		internal VideoCaptureDevice VideoSource
		{
			get 
			{
				lock (SyncRoot)
				{
					return videoSource;
				}
			}
			set
			{
				lock (SyncRoot)
				{
					if (videoSource == value)
						return;

					CloseVideoSource();
					videoSource = value;
					OpenVideoSource();
				}
			}
		}

		void OpenVideoSource()
		{
			if (VideoSource == null)
				return;

			VideoSource.DesiredFrameSize = new Size(1024, 768);
			VideoSource.DesiredFrameRate = 30;
			VideoSource.NewFrame += VideoSource_NewFrame;
			VideoSource.Start();
		}

		void CloseVideoSource()
		{
			CurrentFrame = null;
			if (VideoSource == null)
				return;


			if (VideoSource.IsRunning)
				VideoSource.SignalToStop();
			VideoSource.NewFrame -= VideoSource_NewFrame;

			videoSource = null;
		}

		public void ShuttingDown()
		{
			lock (SyncRoot)
			{
				CloseVideoSource();
			}
		}

		void VideoSource_NewFrame(object sender, NewFrameEventArgs eventArgs)
		{
			lock (SyncRoot)
			{
				CurrentFrame = new Bitmap(eventArgs.Frame);
			}
		}



	}
}
